#include "rewine/SymbolResolver.hpp"

#include "rewine/IImage.hpp"
#include "rewine/LoaderSingleton.hpp"

using std::shared_ptr;
using std::string;

namespace rewine
{

bool
SymbolResolver::resolveAndBind(
        IImage *pImage, const std::string& dll, const std::string& symbol, uint16_t hint,
        ValueSynchronizer& valueSynchronizer, bool bSyncNow) const {
    //auto pOpened = g_Loader->openImage(dll, false);

    string sDll(dll); lower_string(sDll);
    auto pLib = g_Loader->getLibManager().get(sDll);
    if (!pLib) {
        return false;
    }

    // spImported can be different from pOpened
    std::shared_ptr<IImage> spImported;
    auto pExport = pLib->resolve(symbol, hint, &spImported);
    if (!pExport) {
        return false;
    }

    valueSynchronizer.follow(pExport->getValueSynchronizerRef());
    if (bSyncNow) {
        valueSynchronizer.getValue();
    }
    if (pImage) {
        pImage->setImport(spImported);
    } else {
        //TODO workaround for binding a no-owner IExport
        //     ideal solution is refining the imported-by lists of CImage
        spImported->setPinned(true);
    }
    return true;
}

} // namespace rewine
